<?php

namespace core;

class File
{
	/************************************************************
	*   					Properties							*
	************************************************************/




	/************************************************************
	*   					Private methods						*
	************************************************************/


	/**
	 * Opens file in given mode and returns its filepointer
	 *
	 * @param	string	$file
	 * @param	string	$type
	 * @return	resource
	 */
	private function Open($file, $type)
	{
		if (file_exists($file))
		{
			$fp = @fopen($file, $type);

			if (!$fp)
			{
				service("debug")->error("File $file could not be read");
			}
			else
			{
				return $fp;
			}
		}
		else
		{
			service("debug")->error("File $file not found");
		}
	}

	/**
	 * Writes string to a file
	 *
	 * @param	resource	$fp
	 * @param	string		$text
	 * @return	boolean
	 */
	private function Write($fp, $text)
	{
		@fwrite($fp, $text) or service("debug")->error("Couldn't write to file");
		return true;
	}




	/************************************************************
	*   					Public methods						*
	************************************************************/


	/**
	 * Returns contents of the file
	 *
	 * @param	string	$file
	 * @return	string
	 */
	public function Read($file)
	{
		$fp = $this->Open($file, "r");

		$content = @fread($fp, filesize($file));

		if (!is_string($content))
		{
			service("debug")->error("File $file could  not be read");
		}

		return $content;
	}

	/**
	 * Returns Simple Xml object created from file $file
	 *
	 * @param	string	$file
	 * @return	object
	 */
	public function LoadXml($file)
	{
		$xml = @simplexml_load_file($file);

		if (!is_file($file))
		{
			service("debug")->error("Error XML-file $file not found");
			return false;
		}

		if (!is_object($xml))
		{
			service("debug")->error("Xml-file $file contains errors");
			return false;
		}
		else
		{
			return $xml;
		}
	}

	/**
	 * Writes mesage to log
	 *
	 * @param string $text
	 */
	public function Log($text)
	{
		return $this->Append(_TEMP_DIR."logs/log.txt", $text."\n");
	}

	public function Append($file, $text)
	{
		$fp = $this->Open($file, 'a');

		fwrite($fp, $text);
	}

	/**
	 * To be used instead of require/include
	 *
	 * @param unknown_type $file
	 */
	public function ImportScript($file, $force = false, $required = true)
	{
		if (!is_string($file))
		{
			return service("debug")->error("Expected string for script file");
		}

		if (file_exists($file))
		{
			if ($force)
			{
				return require($file);
			}
			else
			{
				return require_once($file);
			}
		}
		elseif (!$required)
		{
			return false;
		}
		else
		{
			return service("debug")->error("Script file '$file' wasn't found");
		}
	}

	/**
	 * To be used instead of require/include
	 *
	 * @param unknown_type $file
	 */
	public function ImportScriptSelective($file, $force = false, $required = true)
	{
		print "!<br />";
		if (!is_string($file))
		{
			return service("debug")->error("Expected string for script file");
		}

		$projectFile = _PROJECT_DIR . $file;
		$systemFile = _SYSTEM_DIR . $file;

		if (file_exists($projectFile))
		{
			return $this->ImportScript($projectFile, $force, $required);
		}
		elseif (file_exists($systemFile))
		{
			return $this->ImportScript($systemFile, $force, $required);
		}
		else
		{
			return service("debug")->error("Script file '$file' wasn't found");
		}
	}

	/**
	 * Returns array of directory contents
	 *
	 * @param	string	$path
	 * @param	boolean	$pattern
	 * @return	array
	 */
	public function GetDirContent($path, $pattern = false)
	{
		if (!is_dir($path))
		{
			return array();//service("debug")->error("$path is not a directory");
		}

		$content = scandir($path);

		foreach ($content as &$item)
		{
			if ($item !== "." && $item !== "..")
			{
				if (!empty($pattern))
				{
					if (!preg_match("~".$pattern."~i", $item))
					{
						$item = "";
					}
				}
			}
			else
			{
				$item = "";
			}
		}

		$content = array_filter($content);

		return $content;
	}


	/**
	 *	Returns array of collective(system + project) directory contents
	 *
	 * @param	string	$path
	 * @param	boolean	$pattern
	 * @return	array
	 */
	public function GetDirContentSelective($path, $pattern = false)
	{
		$pathProject = $this->GetDirContent(_PROJECT_DIR.$path, $pattern);
		$pathSystem = $this->GetDirContent(_SYSTEM_DIR.$path, $pattern);

		if (!is_array($pathProject))
		{
			$pathProject = array();
		}

		if (!is_array($pathSystem))
		{
			$pathSystem = array();
		}

		$pathProject = array_flip($pathProject);
		$pathSystem = array_flip($pathSystem);

		foreach ($pathProject as $key=>$item)
		{
			if (isset($pathSystem[$key]))
			{
				unset($pathSystem[$key]);
			}
		}

		$pathProject = array_flip($pathProject);
		$pathSystem = array_flip($pathSystem);

		foreach ($pathProject as &$item)
		{
			$item = _PROJECT_DIR . $path . $item;
		}

		foreach ($pathSystem as &$item)
		{
			$item = _SYSTEM_DIR . $path . $item;
		}

		$res = array_merge($pathProject, $pathSystem);

		return $res;
	}
}